package pe.com.fastfood4.rie.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
import pe.com.fastfood4.rie.model.DetalleReserva;
import pe.com.fastfood4.rie.model.Reserva;

/**
 * ReservaDaoImpl.java es la implementacion de ReservaDao.java
 * @author grupo 06 - upc_dew 2010
 */
public class ReservaDaoImpl extends SimpleJdbcDaoSupport implements ReservaDao {

    //protected final Log logger = LogFactory.getLog(getClass());

    /** obtiene las reservas por fecha especifica */
    public List<Reserva> getReservasPorFecha(String fecha) {
        logger.info("fechaStringParameter = " + fecha);

        /** se extrae el año, mes y dia de parametro fecha */
        String anno = fecha.substring(0, 4);
        String mes = fecha.substring(5, 7);
        String dia = fecha.substring(8, 10);

        logger.info("Obteniendo Reservas con Año: " + anno + ", Mes: " + mes + ", Dia: " + dia);
        
        List<Reserva> reservas = getSimpleJdbcTemplate().query(
            "select distinct idReserva, fecha, estadoReserva, comentarios, idCliente " +
            "from Reservas  " +
            "where (year(fecha) = :anno) and (month(fecha) = :mes) and (day(fecha) = :dia)",
            new ReservaMapper(), 
            new MapSqlParameterSource()
                .addValue("anno", anno)
                .addValue("mes", mes)
                .addValue("dia", dia));
        return reservas;
    }

    /** actualiza estado de reserva a Confirmada, Rechazada o Facturada */
    public void actualizarReserva(String idReserva, String estado) {
        logger.info("Actualizando Reserva con ID: " + idReserva + ", estado: " + estado);
        int count = getSimpleJdbcTemplate().update(
            "update Reservas set estadoReserva = :estado where idReserva = :idReserva ",
            new MapSqlParameterSource()
                .addValue("idReserva", idReserva)
                .addValue("estado", estado));
        logger.info("Rows affected: " + count);
    }

    /** registra los detalles de reserva en la base de datos */
    public void registrarDetalleReserva(DetalleReserva detalleReserva) {
        logger.info("Saving DetalleReserva: " + detalleReserva.getIdDetalleReserva());
	int count = getSimpleJdbcTemplate().update(
            "insert into DetalleReservas (idDetalleReserva, idPlato, cantidadPlatos) " +
            "values(:idDetalleReserva, :idPlato, :cantidadPlatos)",
            new MapSqlParameterSource()
                .addValue("idDetalleReserva", detalleReserva.getIdDetalleReserva())
                .addValue("idPlato", detalleReserva.getIdPlato())
                .addValue("cantidadPlatos", detalleReserva.getCantidadPlatos())
        );
	logger.info("Rows affected: " + count);
    }

    /** registra una reserva en la base de datos */
    public void registrarReserva(Reserva reserva) {
        logger.info("Saving Reserva: " + reserva.getIdReserva());
	int count = getSimpleJdbcTemplate().update(
            "insert into Reservas (idReserva, fecha, estadoReserva, comentarios, idCliente, idDetalleReserva) " +
            "values(:idReserva, :fecha, :estadoReserva, :comentarios, :idCliente, :idDetalleReserva)",
            new MapSqlParameterSource()
                .addValue("idReserva", reserva.getIdReserva())
                .addValue("fecha", reserva.getFecha())
                .addValue("estadoReserva", reserva.getEstadoReserva())
                .addValue("comentarios", reserva.getComentarios())
                .addValue("idCliente", reserva.getIdCliente())
                .addValue("idDetalleReserva", reserva.getIdDetalleReserva())
        );
	logger.info("Rows affected: " + count);
    }

    /** obtiene ultimo codigo de reserva registrado en la base de datos */
    public int getUltimoIdReserva() {
        logger.info("Obteniendo UltimoIdReserva!");
        int ultimoIdReserva = getSimpleJdbcTemplate().queryForInt(
            "select distinct idReserva from Reservas where idReserva = (select max(idReserva) from Reservas)");
        return ultimoIdReserva;
    }

    /** obtiene las reservas confirmadas por fecha especifica */
    public List<Reserva> getReservasConfirmadasPorFecha(String fecha) {
        logger.info("fechaStringParameter = " + fecha);

        /** se extrae el año, mes y dia de parametro fecha */
        String anno = fecha.substring(0, 4);
        String mes = fecha.substring(5, 7);
        String dia = fecha.substring(8, 10);

        logger.info("Obteniendo Reservas confirmadas con Año: " + anno + ", Mes: " + mes + ", Dia: " + dia);

        List<Reserva> reservas = getSimpleJdbcTemplate().query(
            "select distinct idReserva, fecha, estadoReserva, comentarios, idCliente " +
            "from Reservas  " +
            "where (year(fecha) = :anno) and (month(fecha) = :mes) and (day(fecha) = :dia) " +
            "and estadoReserva = 'Confirmada'",
            new ReservaAFacturarMapper(),
            new MapSqlParameterSource()
                .addValue("anno", anno)
                .addValue("mes", mes)
                .addValue("dia", dia));
        return reservas;
    }

    /** obtiene una reserva por codigo de reserva (idReserva) */
    public Reserva getReservaPorId(String idReserva) {
        logger.info("Obteniendo Reserva por idReserva = " + idReserva);

        Reserva reserva = getSimpleJdbcTemplate().queryForObject(
                "select distinct idReserva, fecha, estadoReserva, comentarios, idCliente " +
                "from Reservas  " +
                "where idReserva = :idReserva",
                new ReservaAFacturarMapper(),
                new MapSqlParameterSource().addValue("idReserva", idReserva));
        return reserva;
    }

    private static class ReservaMapper implements ParameterizedRowMapper<Reserva> {

        public Reserva mapRow(ResultSet rs, int rowNum) throws SQLException {
            Reserva reserva = new Reserva();
            reserva.setIdReserva(rs.getInt("idReserva"));
            reserva.setFecha(rs.getString("fecha"));
            reserva.setEstadoReserva(rs.getString("estadoReserva"));
            reserva.setComentarios(rs.getString("comentarios"));
            reserva.setIdCliente(rs.getInt("idCliente"));
            return reserva;
        }
    }

    private static class ReservaAFacturarMapper implements ParameterizedRowMapper<Reserva> {

        public Reserva mapRow(ResultSet rs, int rowNum) throws SQLException {
            Reserva reserva = new Reserva();
            reserva.setIdReserva(rs.getInt("idReserva"));
            reserva.setFecha(rs.getString("fecha"));
            reserva.setEstadoReserva(rs.getString("estadoReserva"));
            reserva.setComentarios(rs.getString("comentarios"));
            reserva.setIdCliente(rs.getInt("idCliente"));
            return reserva;
        }
    }
}
